package com.muyu.api.response;

import com.muyu.api.enums.ApiStatusEnum;
import com.muyu.api.exception.BusinessException;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
 * @ClassName: ResultResponse
 * @Author: Zirun.Xin
 * @Date: 2025/4/9 下午3:30
 * @Version: 1.0
 * @Description: 统一API响应结构体（泛型基础类）
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ResultResponse<T> implements Serializable {

    /**
     * 业务状态码（遵守RESTful规范）
     *
     * @see ApiStatusEnum
     */
    protected int code;

    /**
     * 业务提示信息（支持国际化Key或直接文本）
     */
    protected String message;

    /**
     * 服务器响应时间（ISO8601格式）
     *
     * @see <a href="https://www.iso.org/iso-8601-date-and-time-format.html">ISO8601标准</a>
     */
    protected Long serverTime;

    /**
     * 响应业务数据（泛型容器）
     */
    protected T data;

    /**
     * 请求是否成功标识
     */
    protected Boolean success;

    /**
     * 全参数构造器（protected级别防止误用）
     *
     * @param code    状态码
     * @param message 提示信息
     * @param data    业务数据
     * @param success 是否成功
     */
    protected ResultResponse(int code, String message, T data, Boolean success) {
        this.code = code;
        this.message = message;
        this.data = data;
        this.success = success;
        this.serverTime = System.currentTimeMillis();
    }

    /*------------ 核心工厂方法 ------------*/

    /**
     * 创建成功响应（默认消息）
     *
     * @param data 要返回的业务数据
     * @param <T>  数据类型
     * @return 成功响应实例
     */
    public static <T> ResultResponse<T> ok(T data) {
        return new ResultResponse<>(ApiStatusEnum.SUCCESS.getCode(), ApiStatusEnum.SUCCESS.getDesc(), data, true);
    }

    /**
     * 创建自定义消息的成功响应
     *
     * @param data    要返回的业务数据
     * @param message 自定义成功消息
     * @param <T>     数据类型
     * @return 成功响应实例
     */
    public static <T> ResultResponse<T> ok(T data, String message) {
        return new ResultResponse<>(ApiStatusEnum.SUCCESS.getCode(), message, data, true);
    }

    /**
     * 创建预定义状态的失败响应
     *
     * @param ApiStatusEnum 失败状态枚举
     * @param <T>           数据类型
     * @return 失败响应实例
     */
    public static <T> ResultResponse<T> fail(ApiStatusEnum ApiStatusEnum) {
        return new ResultResponse<>(ApiStatusEnum.getCode(), ApiStatusEnum.getDesc(), null, false);
    }

    /**
     * 创建完全自定义的失败响应
     *
     * @param code    自定义状态码
     * @param message 错误提示信息
     * @param <T>     数据类型
     * @return 失败响应实例
     */
    public static <T> ResultResponse<T> fail(int code, String message) {
        return new ResultResponse<>(code, message, null, false);
    }

    /*------------ 流畅接口方法 ------------*/

    /**
     * 链式设置状态码
     *
     * @param code 要设置的状态码
     * @return 当前实例
     */
    public ResultResponse<T> withCode(int code) {
        this.code = code;
        return this;
    }

    /**
     * 链式设置提示消息
     *
     * @param message 要设置的消息
     * @return 当前实例
     */
    public ResultResponse<T> withMessage(String message) {
        this.message = message;
        return this;
    }

    /**
     * 链式设置业务数据
     *
     * @param data 要设置的数据
     * @return 当前实例
     */
    public ResultResponse<T> withData(T data) {
        this.data = data;
        return this;
    }

    /*------------ 异常转换 ------------*/

    /**
     * 从业务异常创建响应对象
     *
     * @param ex  业务异常实例
     * @param <T> 数据类型
     * @return 失败响应实例
     */
    public static <T> ResultResponse<T> fromException(BusinessException ex) {
        return new ResultResponse<>(ex.getCode(), ex.getMessage(), null, false);
    }
}
